package com.vhly.remoteapi;

import com.vhly.remoteapi.yahoo.contact.Category;
import com.vhly.remoteapi.yahoo.contact.Contact;
import com.vhly.remoteapi.yahoo.contact.ContactObject;
import com.vhly.remoteapi.yahoo.contact.Field;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.YahooApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;

import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: vhly[FR]
 * Date: 2010-12-5
 * Time: 12:43:12
 * Email: vhly@163.com
 */
public class YahooClient extends APIClient {
    private OAuthService oauth;

    public OAuthService getOAuthService() {
        if (oauth == null) {
            ServiceBuilder builder = new ServiceBuilder();
            builder.provider(YahooApi.class); // for J2SE
//            builder.provider((new YahooApi()).getClass());  // for Android

            // set your consumer info
            builder.apiKey("dj0yJmk9bFFNaUVpcG5ySmYxJmQ9WVdrOU4wWnVOM0JoTkdFbWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD1kZQ--");
            builder.apiSecret("53fa74ceb4f9d6765e504349053afecfdc2c91a8");
            oauth = builder.build();
        }
        return oauth;
    }

    @Override
    public boolean loadToken() {
        boolean ret = false;
        File f = new File("accessToken.dat");
        if (f.exists()) {
            FileInputStream fin = null;
            DataInputStream din = null;
            try {
                fin = new FileInputStream(f);
                din = new DataInputStream(fin);
                accessToken = new Token(din.readUTF(), din.readUTF());
                int len = din.read();
                for (int i = 0; i < len; i++) {
                    accessToken.addOther(din.readUTF(), din.readUTF());
                }
                ret = true;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (din != null) {
                    try {
                        din.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fin != null) {
                    try {
                        fin.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return ret;
    }

    @Override
    public boolean saveToken() {
        boolean bret = false;
        if (accessToken != null) {
            File f = new File("accessToken.dat");
            FileOutputStream fout = null;
            DataOutputStream dout = null;
            try {
                fout = new FileOutputStream(f);
                dout = new DataOutputStream(fout);
                dout.writeUTF(accessToken.getToken());
                dout.writeUTF(accessToken.getSecret());
                Hashtable<String, String> os = accessToken.getOthers();
                int len = 0;
                if (os != null) {
                    len = os.size();
                    dout.write(len);
                    Enumeration<String> ks = os.keys();
                    while (ks.hasMoreElements()) {
                        String kn = ks.nextElement();
                        dout.writeUTF(kn);
                        dout.writeUTF(os.get(kn));
                    }
                } else {
                    dout.write(0);
                }
                bret = true;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (dout != null) {
                    try {
                        dout.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fout != null) {
                    try {
                        fout.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return bret;
    }

    public String getMeGUID() {
        String ret;
        OAuthRequest req = new OAuthRequest(Verb.GET, "http://social.yahooapis.com/v1/me/guid");
        ret = invoke(req);
        req = null;
        return ret;
    }

    public String getContactSync(String rev) {
        String ret;
        OAuthRequest req = new OAuthRequest(Verb.GET, "http://social.yahooapis.com/v1/user/SPZD2ZIEGO23K4J4FLMEGJY2N4/contacts?view=sync&rev=" + rev);
        ret = invoke(req);
        req = null;
        return ret;
    }

    /**
     * Sync to Server , HTTP Method must is PUT
     * @param cos ContactObjects
     * @param clientrev ver
     * @return String xml
     */
    public String syncContacts(Vector<ContactObject> cos, String clientrev) {
        String ret = null;
        if (cos != null) {
            int size = cos.size();
            ContactObject co;
            StringBuffer sb = new StringBuffer("<?xml version=\"1.0\"?>\n<contactsync xmlns=\"http://blah/\"");
            sb.append(" rev=\"").append(clientrev).append("\">\n");
            Category cat;
            Contact cont;
            for (int i = 0; i < size; i++) {
                co = cos.get(i);
                if (co instanceof Category) {
                    cat = (Category) co;
                    sb.append("<categories>\n").append("<op>").append(cat.status).append("</op>\n");
                    switch (cat.status) {
                        case ADD:
                            sb.append("<name>").append(cat.name).append("</name>\n");
                            break;
                        case UPDATE:
                            sb.append("<old><id>").append(cat.id).append("</id></old>\n");
                            sb.append("<new><name>").append(cat.name).append("</name></new>\n");
                            break;
                        case REMOVE:
                            sb.append("<id>").append(cat.id).append("</id>\n");
                            // not both name and id
//                            sb.append("<name>").append(cat.name).append("</name>");
                            break;
                    }
                    sb.append("</categories>\n");
                } else if (co instanceof Contact) {
                    cont = (Contact) co;
                    sb.append("<contacts>\n");
                    sb.append("<op>").append(cont.status).append("</op>\n");
                    Vector<Field> fds = cont.fields;
                    if (fds != null) {
                        int sz = fds.size();
                        Field fd;
                        for (int j = 0; j < sz; j++) {
                            sb.append("<fields>\n");
                            fd = fds.get(j);
                            sb.append("<op>").append(fd.status).append("</op>\n");
                            sb.append("<type>").append(fd.type).append("</type>\n");
                            sb.append("<value>");
                            sb.append(fd.value.toXML());
                            sb.append("</value>\n");
                            sb.append("</fields>\n");
                        }
                    }
                    sb.append("</contacts>\n");
                }
            }
            sb.append("</contactsync>");
            String postContent = sb.toString();
            System.out.println("postContent = " + postContent);
            OAuthRequest req = new OAuthRequest(Verb.PUT, "http://social.yahooapis.com/v1/user/SPZD2ZIEGO23K4J4FLMEGJY2N4/contacts");
            req.addPayload(postContent);
            req.addHeader("Content-Type", "application/xml");
            ret = invoke(req);
        }
        return ret;
    }
}
